//+------------------------------------------------------------------+
//|                                                  get 3 level.mq4 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, Pham Thai Son."
#property link      "http://www.future.is.now"
//---- input parameters 
extern int period = 50;
extern double Period1=5; 
extern double Period2=13; 
extern double Period3=34; 
extern string   Dev_Step_1="1,3";
extern string   Dev_Step_2="8,5";
extern string   Dev_Step_3="21,12";
extern int Symbol_1_Kod=140;
extern int Symbol_2_Kod=141;
extern int Symbol_3_Kod=142;
extern double Lots = 0.1;
//---- for skipping continous loss trade
extern int max_loss_continuos = 3;
extern int bar_skipped = 3;
extern double macdThresold = 0.00015;
int skip_order = 0;
bool skipping_status = false; // skipping status
int MinStopDist;

int a,b,c,tmp;
//----
double ZZ_0, ZZ_1, ZZ_2, ZZ_3, ZZ_4, ZZ_5, ZZ_4_60;
double MacdCurrent, MacdPrevious, SignalCurrent;
double SignalPrevious, MaCurrent, MaPrevious;
double LowLast, LowCurrent, LowPrevious;
double HighLast, HighCurrent, HighPrevious;
double MALast,MACurrent,MAPrevious;
double MA;
double TrendStrength = 0;
int barLast, barCurrent, barPrevious;      // position or previous 3 bar peak
int typeLast=0;
int typeCurrent=0;
int typePrevious=0; //-1 is peak low, 1 is peak hi
int cnt, ticket, total;
// buysignal 0 is not trend, 1 is buy signal, -1 is sell signal   
int sema_signal = 0;
int macd_signal = 0;
int signal = 0;
int tmp_signal = 0;
// store bar  which trade is placed
int ThisBarTrade = 0; 
// store last trade type -1 sell, 1 buy
int ThisTrade = 0;
// store trend strength
double LowContinous = 0;
// now we will do many order by the trend strength not 1 any more 
// huge profit is here when market has strong trend :)
int orderCount = 0;
// store the strength of the market since order was made
double diff[1000]; 
// store the ticket id of previous order
int ticketID[1000];
// store the type of the order, 1 is by, -1 is sell
int orderType[1000];
// store status of the order true is going, false is closed
bool orderStatus[1000];
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   MinStopDist = MarketInfo(Symbol(), MODE_STOPLEVEL);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }

int dump()
  {// Dump Variable      
      Print("typeLast = " + typeLast);
      Print("barLast = " + barLast);
      Print("LowLast = " + LowLast);    
      
      Print("typePrevious = " + typePrevious);
      Print("barPrevious = " + barPrevious);
      Print("HighPrevious = " + HighPrevious);
      
      Print("typeCurrent = " + typeCurrent);      
      Print("barCurrent = " + barCurrent);
      Print("LowCurrent = " + LowCurrent); 
  
  
      return(0);
  }
int dump1()
  {
      Print("typeLast = " + typeLast);
      Print("barLast = " + barLast);
      Print("HighLast = " + HighLast);           
      
      Print("typePrevious = " + typePrevious);
      Print("barPrevious = " + barPrevious);
      Print("LowPrevious = " + LowPrevious);      
      
      Print("typeCurrent = " + typeCurrent);
      Print("barCurrent = " + barCurrent);
      Print("HighCurrent = " + HighCurrent);   
  }

int start()
  {   
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external 
// variables (Lots, StopLoss, TakeProfit, 
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }  
// to simplify the coding and speed up access
// data are put into internal variables

// get macd
   MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
   MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
   SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0);
   SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
   

//---- get 3 level zz semafor
//   ZZ_0=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,0,0);
//   ZZ_1=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,1,0);
//   ZZ_2=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,2,0);
//   ZZ_3=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,3,0);
   ZZ_4=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,4,0);
   ZZ_5=iCustom(Symbol(),0,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,5,0);
   MA = iMA(NULL, 0, period, 0, MODE_SMA, PRICE_TYPICAL, 0);
   //ZZ_4_60=iCustom(Symbol(),60,"3_Level_ZZ_Semafor",Period1,Period2,Period3,Dev_Step_1,Dev_Step_2,Dev_Step_3,Symbol_1_Kod,Symbol_2_Kod,Symbol_3_Kod,4,0);
   
   
   int    counted_bars=IndicatorCounted();
   if(ZZ_4 > 0) {     
      // if current peak is low and the bar diff is more than 3 bar
      // or if current peak is high, shift 3 peak point
      if(typeCurrent == 1 || (typeCurrent == -1 && Bars - barCurrent > 3))   
      {        
         barLast = barPrevious;   // shift last to previous
         typeLast = typePrevious;
         LowLast = LowPrevious;
         MALast = MAPrevious;
         
         barPrevious = barCurrent; // shift previous to current
         typePrevious = typeCurrent;        
         HighPrevious = HighCurrent;   
         MAPrevious = MACurrent;         
      }   
         
      typeCurrent = -1;        // Set current  low 
      LowCurrent = Low[0];
      barCurrent = Bars;  
      MACurrent = MA;                 
         
      // if we trade at bottom , check if current trend is only minor trend(previous trend is much stronger 
      if(typeLast == -1 && typePrevious == 1 && typeCurrent == -1) 
       { 
      TrendStrength += LowCurrent - LowLast;
         if(MACurrent > MALast){  // higher low then buy at bottom
               // Buy signal is triggered and we buy at bottom                
               //   Print("Previous low is :" + LowLast);
               //   Print("Current low is : " + LowCurrent);
            sema_signal = 1;               
         }    
         else  sema_signal = 0;
       }  
      if(typeLast == 1 && typePrevious == 1 && typeCurrent == -1)
       {
         sema_signal = 1; 
       }
      //Print("barCurrent = " + barCurrent);  
                     
      Print("MACurrent = " + MACurrent);
      Print("MALast = " + MALast);
      //dump();  
   }
   if(ZZ_5 > 0)  { 
      // if current peak is low and the bar diff is more than 3 bar
      // or if current peak is low shift 3 peak point
      if(typeCurrent == -1 || (typeCurrent == 1 && Bars - barCurrent > 3))   
      {
         
         barLast = barPrevious;         // shift last to previous
         typeLast = typePrevious;
         HighLast = HighPrevious;
         MALast = MAPrevious;
         
         barPrevious = barCurrent;      // shift previous to current         
         typePrevious = typeCurrent;         
         LowPrevious = LowCurrent; 
         MAPrevious = MACurrent;  
         
      }            
      
      typeCurrent = 1;              // Set current high    
      HighCurrent = High[0];        
      barCurrent = Bars;    
      MACurrent = MA;
      
      // if we trade at bottom , check if current trend is only minor trend(previous trend is much stronger  
      if(typeLast == 1 && typePrevious == -1 && typeCurrent == 1)   
      {
      TrendStrength -= HighLast - HighCurrent;
         if(MACurrent < MALast){  // lower highs
               // Buy signal is triggered we sell at top                
               //   Print("Previous high is :" + HighLast);
               //   Print("Current high is : " + HighCurrent);
                  sema_signal = -1;               
         }  else sema_signal = 0;
      }   
      if(typeLast == -1 && typePrevious == -1 && typeCurrent == 1)
       {
         sema_signal = -1; 
       }   
      //Print("barCurrent = " + barCurrent); 
      Print("MACurrent = " + MACurrent);
      Print("MALast = " + MALast);
      //dump1();
            
   }
//---- check condition wherether by or sell
   if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious<SignalPrevious && MathAbs(MacdCurrent) >= macdThresold){
      macd_signal = 1;
   }
   if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && MathAbs(MacdCurrent) >= macdThresold){
      macd_signal = -1;
   }
//---- save previous signal
   tmp_signal = signal;
   if(sema_signal == 1  && macd_signal == 1){
      signal = 1;     
   }
   
   if(sema_signal == -1 && macd_signal == -1){
      signal = -1;      
   }   
//---- check if signal is change, if signal change or no order current then place a new order   
//---- we comment this line cause of we will place many order not only 1
//----
   place_order();
   return(0);   
  }
//+------------------------------------------------------------------+

int place_order()
  {
         if(AccountFreeMargin()<(1000*Lots))
         {
          Print("We have no money. Free Margin = ", AccountFreeMargin());
          return(0);  
         }     
         Lots = MathRound(AccountBalance()/1000) * 0.1;
         // Check last trade if it is stop loss order
         int last_trade=HistoryTotal();
         int last_stoploss_type =0 ; // store last stop loss trade, 1 is buy, -1 sell, 0 is no stoploss
         if(last_trade>0)
         {
            if(OrderSelect(last_trade-1,SELECT_BY_POS,MODE_HISTORY)==true)
            {
             if(OrderSymbol()==Symbol() && OrderClosePrice()==OrderStopLoss() && OrderType() == OP_BUY)
                {
                 //Print("Last closed order was buy OrderType = ",OrderType(),"  Time = ",TimeToStr(OrderCloseTime()),"  close at StopLoss  ",OrderClosePrice());                                  
                 last_stoploss_type = 1;
                }  
             if(OrderSymbol()==Symbol() && OrderClosePrice()==OrderStopLoss() && OrderType() == OP_SELL)
                {
                 //Print("Last closed order was sell OrderType = ",OrderType(),"  Time = ",TimeToStr(OrderCloseTime()),"  close at StopLoss  ",OrderClosePrice());                                  
                 last_stoploss_type = -1;
                }    
            }
         }    
         if(signal ==1){       
            //---- send buy Order   
            //---- if buy in this bar do not buy more
            // too close to pit point so do not place order
            if(LowCurrent > Bid - MinStopDist*Point ||  Bars -  ThisBarTrade < 10){               
               //ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,Bid - MinStopDist*Point,0,"macd sample",16384,0,Green);
            }else{
               ObjectCreate("Arrow" + Bid, OBJ_ARROW, 0, TimeCurrent(), Bid); //draw an up arrow
               ObjectSet("Arrow" + Bid, OBJPROP_STYLE, STYLE_SOLID);
               ObjectSet("Arrow" + Bid, OBJPROP_ARROWCODE, SYMBOL_ARROWUP);
               ObjectSet("Arrow" + Bid, OBJPROP_COLOR,Green);
               ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,LowCurrent,0,"macd sample",16384,0,Green); // stoploss at current low
               ThisBarTrade = Bars; // current bar which trade is placed
               ThisTrade = 1;
            }            
            // clear signal            
            close_order();
            sema_signal = 0;
            signal = 0;  
            return(0); 
         }
         if(signal == -1){            
            //---- send sell order
            //---- if buy in this bar do not buy more
            // too close to pit point so do not place order
            if(HighCurrent < Ask + MinStopDist*Point || Bars - ThisBarTrade < 10){              
               //ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,Ask + MinStopDist*Point,0,"macd sample",16384,0,Red);
            }else{
               ObjectCreate("Arrow" + Ask, OBJ_ARROW, 0, TimeCurrent(), Ask); //draw an down arrow
               ObjectSet("Arrow" + Ask, OBJPROP_STYLE, STYLE_SOLID);
               ObjectSet("Arrow" + Ask, OBJPROP_ARROWCODE, SYMBOL_ARROWDOWN);
               ObjectSet("Arrow" + Ask, OBJPROP_COLOR,Red); 
               ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,HighCurrent,0,"macd sample",16384,0,Red); // stoploss at current hi
               ThisBarTrade = Bars; // current bar which trade is placed
               ThisTrade = -1;
            }
            // clear signal           
            close_order();           
            sema_signal = 0;
            signal = 0;
            return(0);
         }     
  }          

int close_order()
  {
   total=OrdersTotal();
//---- if there is 1 order then signal is changed we take profit.
//---- now we scan all order, see if an order should be closed.
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   // check for opened position 
         OrderSymbol()==Symbol())  // check for symbol
        {
         if(OrderType()==OP_BUY)   // long position is opened
           {
            // should it be closed?
            if(sema_signal == -1)
                {
                  OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
                }            
           }
         else                      // go to short position
           {
            // should it be closed?
            if(sema_signal == 1)
              {
                  OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
              }
           }
        }
     }
   return(0);
  }
  

